<template>
  <div class="wedding-editor" ref="editor">
    <header class="editor-header">
      <a href="javascript:;"></a>
      <a href="javascript:;" class="minimum"></a>
      <a href="javascript:;" class="maximum"></a>
    </header>
    <!-- 日期 -->
    <p class="code">Last login: <span>{{ startDate }}</span> on ttys001</p>
    <!--代码编辑区-->
    <pre>
      <code v-html="highlightedCode"></code>
    </pre>
    <!-- 打开邀请函 -->
    <div class="editor-open" v-if="hasShow" @click="canOpen = true">
      <svg viewBox="0 0 24 24" width="18" height="18" stroke="currentColor" stroke-width="2" fill="none"
        stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1">
        <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
        <line x1="9" y1="3" x2="9" y2="21"></line>
      </svg>
    </div>
    <!-- 打开彩票 -->
    <div class="lottery-open" v-if="id" @click="LotteryShow = !LotteryShow; tipShow = false">
      <svg t="1696409046125" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
        p-id="4050" width="18" height="18">
        <path
          d="M511.630075 64.101947c-246.795872 0-447.554222 200.779839-447.554222 447.555246 0 246.775406 200.759373 447.554222 447.554222 447.554222 246.77643 0 447.534779-200.778816 447.534779-447.554222C959.163831 264.881786 758.406504 64.101947 511.630075 64.101947zM511.630075 906.040425c-217.46894 0-394.381186-176.933735-394.381186-394.382209 0-217.449497 176.912245-394.382209 394.381186-394.382209 217.469963 0 394.382209 176.932712 394.382209 394.382209C906.012284 729.105666 729.099015 906.040425 511.630075 906.040425zM396.039453 656.30664c49.843198 0 90.39887-40.556695 90.39887-90.420359L486.438323 378.570081c0-49.864688-40.556695-90.420359-90.39887-90.420359-49.863664 0-90.421382 40.556695-90.421382 90.420359l0 187.315176C305.618071 615.749946 346.175789 656.30664 396.039453 656.30664zM358.770642 378.570081c0-20.557198 16.71059-37.248346 37.268812-37.248346 20.516266 0 37.226856 16.691147 37.226856 37.248346l0 187.315176c0 20.557198-16.71059 37.247322-37.226856 37.247322-20.558222 0-37.268812-16.691147-37.268812-37.247322L358.770642 378.570081zM627.220696 288.149722c-49.842175 0-90.420359 40.556695-90.420359 90.420359l0 143.138024 0 34.600029 0 9.576099c0 49.864688 40.578184 90.420359 90.420359 90.420359 49.864688 0 90.420359-40.556695 90.420359-90.420359l0-44.177152c0-49.863664-40.556695-90.420359-90.420359-90.420359-13.297864 0-25.851784 3.060709-37.225833 8.250918l0-60.969607c0-20.557198 16.71059-37.248346 37.225833-37.248346 20.558222 0 37.268812 16.691147 37.268812 37.248346l0 26.349111c0 14.683421 11.872399 26.596751 26.577309 26.596751 14.684444 0 26.575262-11.913331 26.575262-26.596751l0-26.349111C717.641055 328.705394 677.084361 288.149722 627.220696 288.149722zM627.220696 484.460784c20.558222 0 37.268812 16.71059 37.268812 37.247322l0 44.177152c0 20.557198-16.71059 37.247322-37.268812 37.247322-20.515243 0-37.225833-16.691147-37.225833-37.247322l0-9.576099 0-34.600029C589.994863 501.172397 606.705454 484.460784 627.220696 484.460784zM685.379281 699.717336 337.881892 699.717336c-14.684444 0-26.596751 11.891841-26.596751 26.575262 0 14.684444 11.912307 26.576285 26.596751 26.576285l347.497389 0c14.684444 0 26.595728-11.891841 26.595728-26.576285C711.975009 711.6102 700.062701 699.717336 685.379281 699.717336z"
          fill="#a9895d" p-id="4051"></path>
      </svg>
    </div>
    <div class="openTips" v-if="id && tipShow">
      <div>←</div>
      <div>
        <div>这儿有一张</div>
        <div>来自未来的彩票~</div>
      </div>
    </div>
    <Lottery :id="id" v-show="LotteryShow" />
    <Executions :canExecute="canExecute" @onUpdating="scrollToBottom" @onFinish="canOpen = true" />
    <invitation :canOpen="canOpen" @onClose="canOpen = false, hasClosed = true" @sendBarrage="onAfterSending" />
    <Barrage :wish="wish" :canStart="canStart" />
  </div>
</template>

<script>
import Prism from "prismjs";
import "prismjs/themes/prism-okaidia.css";
import "../utils/raf";
import data from "../mock/data";

import Lottery from "./Lottery.vue";
import Executions from "./Executions";
import Invitation from "./Invitation";
import Barrage from "./Barrage";

export default {
  name: "Editor",
  components: { Executions, Invitation, Barrage, Lottery },
  data() {
    return {
      tipShow: true,
      id: new URLSearchParams(location.search).get("id"),
      startDate: "",
      code: data.code,
      currentCode: "",
      isCursorVisible: 1,
      canExecute: false,
      canOpen: false,
      wish: "",
      hasClosed: false,
      canStart: false,
      LotteryShow: false,
    };
  },
  mounted() { },
  created() {
    this.startDate = new Date().toDateString();
    this.progressivelyTyping();
  },
  updated() {
    this.scrollToBottom();
  },
  computed: {
    hasShow() {
      return (this.canStart || this.hasClosed) && !this.canOpen;
    },
    highlightedCode() {
      const code = Prism.highlight(
        this.currentCode,
        Prism.languages.javascript
      );
      const codeWithCursor = `${code}<span style="opacity:${this.isCursorVisible
        }"> ▍</span>`;
      return codeWithCursor;
    },
  },
  methods: {
    scrollToBottom() {
      // 保持页面一直滚到最下面
      this.$refs.editor.scrollTop = 100000;
    },
    // 代码输入
    progressivelyTyping() {
      return new Promise((resolve) => {
        let count = 0,
          typingCount = 0,
          typing;
        // 写代码每一帧的函数
        let step = () => {
          let randomNumber = Math.round(Math.random() * 6);
          // 摸你打字的随机速度
          if (count % 2 === 0 && randomNumber % 4 === 0) {
            this.currentCode = this.code.substring(0, typingCount);
            typingCount++;
          }
          // 大约每 24 帧光标闪动一次
          if (count % 24 === 0) {
            this.isCursorVisible = this.isCursorVisible === 0 ? 1 : 0;
          }
          count++;
          if (typingCount <= this.code.length) {
            typing = setTimeout(step, 7);
          } else {
            resolve();
            this.canExecute = true;
            cancelAnimationFrame(typing);
          }
        };
        typing = setTimeout(step, 7);
      });
    },
    // 发送弹幕之后
    onAfterSending(wish) {
      this.wish = wish;
      this.canOpen = false;
      setTimeout(() => {
        this.canStart = true;
      }, 800);
    },
  },
};
</script>

<style lang="less">
.wedding-editor {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 15px;
  padding-top: 50px;
  overflow-x: hidden;
  overflow-y: auto;
  z-index: 1;
  transform-origin: 0 0;
  -webkit-transform-origin: 0 0;
  transition: all 1.6s cubic-bezier(0.4, 0, 1, 1);
  -webkit-transition: all 1.6s cubic-bezier(0.4, 0, 1, 1);

  .editor-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    padding: 12px;
    overflow: hidden;
    background: #2b2b48;
    z-index: 3;

    >a {
      float: left;
      display: block;
      width: 16px;
      height: 16px;
      margin-right: 5px;
      border-radius: 8px;
      background: #fc615d;

      &.minimum {
        background: #fdbc40;
      }

      &.maximum {
        background: #34c84a;
      }
    }
  }

  p.code {
    margin: 0;
    color: #bbb;
    line-height: 1.2;
    font-family: "Roboto Mono", "Menlo", "Monaco", Courier, monospace !important;
    font-weight: 500 !important;
    font-size: 16px !important;
  }

  pre {
    margin: 0;
    white-space: pre-wrap;

    code {
      white-space: pre-wrap;
      word-break: break-all;
      font-size: 16px !important;
      margin: 0;
      color: #bbb;
      line-height: 1.2;
      font-family: "Roboto Mono", "Menlo", "Monaco", Courier, monospace !important;
      font-weight: 500 !important;
      background: transparent;
    }
  }

  .editor-open {
    position: fixed;
    right: 20px;
    bottom: 20px;
    width: 40px;
    height: 40px;
    padding: 6px;
    border-radius: 20px;
    text-align: center;
    line-height: 18px;
    border: 5px solid #ffd69b;
    color: #a9895d;
    background: #fff1de;
    z-index: 1000;
  }

  .lottery-open {
    position: fixed;
    left: 20px;
    bottom: 20px;
    width: 40px;
    height: 40px;
    padding: 6px;
    border-radius: 20px;
    text-align: center;
    line-height: 18px;
    border: 5px solid #ffd69b;
    color: #a9895d;
    background: #fff1de;
    z-index: 1000;
  }

  div.openTips {
    position: fixed;
    color: #fff;
    width: 150px;
    left: 70px;
    gap: 6px;
    line-height: 16px;
    z-index: 1000;
    bottom: 24px;
    display: flex;
    align-items: center;
    // animation: identifier forwards 0.4s 12s;
  }

  @keyframes identifier {
    from {
      opacity: 1;
    }

    to {
      opacity: 0;
    }
  }
}
</style>
